package com.auxgroup.hr.front.site.co.process;

import com.alibaba.fastjson.JSON;
import com.auxgroup.hr.front.commons.BaseRetCode;
import com.auxgroup.hr.front.commons.enums.WfStatusEnum;
import com.auxgroup.hr.front.commons.enums.WfTypeEnum;
import com.auxgroup.hr.front.commons.utils.DateUtils;
import com.auxgroup.hr.front.commons.utils.ObjectFieldUtils;
import com.auxgroup.hr.front.commons.vo.BaseResponseVO;
import com.auxgroup.hr.front.commons.vo.UserDTO;
import com.auxgroup.hr.front.dao.domain.*;
import com.auxgroup.hr.front.dao.repository.PsCLeaveDefnVwRepository;
import com.auxgroup.hr.front.dao.repository.PsCLeaveTypeVwRepository;
import com.auxgroup.hr.front.dao.repository.PsCWfPlaveVwRepository;
import com.auxgroup.hr.front.dao.repository.PsCWfStatusVwRepository;
import com.auxgroup.hr.front.hrverify.AuxCheckRequest;
import com.auxgroup.hr.front.hrverify.AuxCheckResponse;
import com.auxgroup.hr.front.service.personnal.PersonalDataService;
import com.auxgroup.hr.front.service.process.WfPlaveHdrService;
import com.auxgroup.hr.front.site.co.BaseWfCO;
import com.auxgroup.hr.front.site.inteceptor.SessionGain;
import com.auxgroup.hr.front.site.vo.process.WfPlaveHdrRespVO;
import com.auxgroup.hr.front.site.vo.process.WfPlaveLsVO;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * 休假申请CO
 *
 * @author wangchangyun
 * @version 创建时间：180527
 */
@RestController
@RequestMapping("${auxgroup.hr.contextPath}/wflavehdr")
public class WfPlaveHdrCO extends BaseWfCO {

    private static final Logger logger = LoggerFactory.getLogger(WfPlaveHdrCO.class);

    @Autowired
    public WfPlaveHdrService wfPlaveHdrService;

    @Autowired
    private PersonalDataService personalDataService;

    @Autowired
    private PsCLeaveTypeVwRepository psCLeaveTypeVwRepository;

    @Autowired
    private PsCLeaveDefnVwRepository psCLeaveDefnVwRepository;
    @Autowired
    private PsCWfStatusVwRepository psCWfStatusVwRepository;
    @Autowired
    private PsCWfPlaveVwRepository psCWfPlaveVwRepository;


    @GetMapping(value = "/getWfPlaveHdr")
    public BaseResponseVO getWfPlaveHdr(String cTransactionNbr, @SessionGain("user") UserDTO user) {
        if (StringUtils.isBlank(cTransactionNbr)) {
            return buildRespone(BaseRetCode.CODE_ERROR_REQUEST_PARAM_NULL);
        }
        PsCWfPlaveHdr laveHdr = wfPlaveHdrService.getWfInfo(cTransactionNbr);
        if (laveHdr == null) {
            return buildRespone(BaseRetCode.CODE_ERROR_PROCESS_NOT_EXIST);
        }

        WfPlaveHdrRespVO respVO = objectMapper.map(laveHdr, WfPlaveHdrRespVO.class);
        //假期剩余
        Map<String, String> leaveMap = personalDataService.getLeavebalInfo(laveHdr.getcWfEmplid());
        if (leaveMap != null) {
            respVO.setAnnualLeave(leaveMap.get("C_ANN_BAL"));
            respVO.setAnnualDisplay(leaveMap.get("C_ANN_VISIBLE"));
            respVO.setOffLeave(leaveMap.get("C_ADJ_BAL"));
            respVO.setOffLeave(leaveMap.get("C_ADJ_VISIBLE"));
        }

        fillBaseWfInfo(user, laveHdr, respVO);

        logger.info(user.getOprId() + ",获取休假流程，单号：" + laveHdr.getcTransactionNbr() + ",开始日期：" + laveHdr.getStartDate() + ",结束日期：" + laveHdr.getEndDate());
        return buildRespone(respVO);
    }

    @GetMapping(value = "/getSavedOne")
    public BaseResponseVO getSavedWfPlaveHdr(String cTransactionNbr, @SessionGain("user") UserDTO user) {
        if (StringUtils.isBlank(cTransactionNbr)) {
            return buildRespone(BaseRetCode.CODE_ERROR_REQUEST_PARAM_NULL);
        }
        PsCWfPlaveHdr laveHdr = wfPlaveHdrService.getWfInfo(cTransactionNbr);
        if (laveHdr == null || !"S".equalsIgnoreCase(laveHdr.getcWfStatus())) {
            return buildRespone(BaseRetCode.CODE_ERROR_PROCESS_NOT_EXIST);
        }
        WfPlaveHdrRespVO respVO = objectMapper.map(laveHdr, WfPlaveHdrRespVO.class);
        return buildRespone(respVO, false);
    }


    @GetMapping(value = "/getSavedList")
    public BaseResponseVO getSavedList(String keywords, @SessionGain("user") UserDTO user) {
//		if(StringUtils.isBlank(cTransactionNbr)){
//			return buildRespone(BaseRetCode.CODE_ERROR_REQUEST_PARAM_NULL);
//		}
        List<PsCWfPlaveVw> vws = psCWfPlaveVwRepository.findByOpridOrderByCWfAppDt(user.getOprId());
//		List<PsCWfPlaveHdr> laveHdrs =  wfPlaveHdrService.querySaveds(user.getEmplId(), keywords);
//		List<Psxlatitem> sks = sysDictService.getSysDict("C_LEAVE_TYPE");
//		Map<String, String> typeMap = new HashMap<>();
//		sks.forEach(s -> typeMap.put(s.getFieldvalue(), s.getXlatshortname()));
        return buildResponeSpecial(vws);
    }

    @GetMapping(value = "/getLeaveLeftValid")
    public BaseResponseVO getLeaveLeftValid(String leaveType) {
        return buildRespone(sysDictService.getLeaveLeftValid(leaveType));
    }


    /**
     * 创建休假流程
     *
     * @param user
     * @return
     */
    @PostMapping(value = "/savePrc")
    public BaseResponseVO saveWfPlaveHdr(@RequestBody PsCWfPlaveHdr laveReq, @SessionGain("user") UserDTO user) {
        logger.info("PrcHdr save param:{}", laveReq);
        laveReq.setcWfEmplid(user.getEmplId());
        WfPlaveHdrRespVO respVO = objectMapper.map(laveReq, WfPlaveHdrRespVO.class);
        if (!valid(respVO)) {
            return buildRespone(BaseRetCode.CODE_ERROR_INPUT_NOT_RIGHT);
        }
        if (!fillBeforeSubmit(laveReq, user)) return buildRespone(BaseRetCode.CODE_ERROR_GET_TRANSACTION_NBR_FAILED);

        //提交前校验可否提交考勤 TODO
        String valideString = wfPlaveHdrService.valide(laveReq, user);
        if (!"成功".equals(valideString)) {
            return buildRespone("000500", valideString);
        }

        laveReq.setcLeaveDays(calcLeaveTime(respVO));
        PsCWfPlaveHdr laveHdr = wfPlaveHdrService.saveWfInfo(laveReq, user);
        if (laveHdr != null) {
            BaseResponseVO resp = submitWf(user, WfTypeEnum.WF_STYPE_LAVE.getType(), laveHdr);
            if (!BaseRetCode.CODE_SUCCESS.getRetCode().equals(resp.getRetCode())
                    && WfStatusEnum.WF_STATUS_S.getStatus().equals(laveHdr.getcWfStatus())) {
//				wfPlaveHdrService.delWfInfo(laveHdr.getcTransactionNbr());
                logger.error("请假流程申请失败");
            }

            return resp;
        } else {
            return buildRespone(BaseRetCode.CODE_ERROR_PROCESS_APPLY_FAIL);
        }
    }

    @PostMapping(value = "/calcLeaveDays")
    public BaseResponseVO calcLeaveDays(@RequestBody WfPlaveHdrRespVO laveReq, @SessionGain("user") UserDTO user) {
        logger.info("calcLeaveDays:{}", laveReq);
        laveReq.setcWfEmplid(user.getEmplId());

        if (valid(laveReq)) {
            return buildRespone(calcLeaveTime(laveReq).toString());
        } else {
            return buildRespone(BaseRetCode.CODE_ERROR_INPUT_NOT_RIGHT);
        }
    }

    @PostMapping(value = "/calcApplyPregnantDays")
    public BaseResponseVO calcApplyPregnantDays(@RequestBody WfPlaveHdrRespVO laveReq, @SessionGain("user") UserDTO user) {
        logger.info("calcLeaveDays:{}", laveReq);
        laveReq.setcWfEmplid(user.getEmplId());

        if (valid(laveReq)) {
            return buildRespone(calcApplyPregnantTime(laveReq).toString());
        } else {
            return buildRespone(BaseRetCode.CODE_ERROR_INPUT_NOT_RIGHT);
        }
    }

    /**
     * 计算产检假总数
     *
     * @param laveReq
     * @return
     */
    private BigDecimal calcApplyPregnantTime(WfPlaveHdrRespVO laveReq) {

        Date startDate = laveReq.getStartDate();
        String pregnantTime = laveReq.getcPregnantTime();
        String emplid = laveReq.getcWfEmplid();
        BigDecimal days = wfPlaveHdrService.calcApplyPregnantTime(emplid, startDate, pregnantTime);

        return days;
    }

    private boolean valid(WfPlaveHdrRespVO laveReq) {
        if (!"L90".equals(laveReq.getcLeaveType())) {
            return !StringUtils.isEmpty(laveReq.getcAcrossDay()) &&
                    !StringUtils.isEmpty(laveReq.getcLeaveType()) &&
                    (
                            (//跨天
                                    laveReq.getcAcrossDay().equals("Y") &&
                                            !StringUtils.isEmpty(laveReq.getcLeaDay2()) &&
                                            !StringUtils.isEmpty(laveReq.getcLeaDay3()) &&
                                            laveReq.getStartDate() != null &&
                                            laveReq.getEndDate() != null
                            ) ||
                                    (//不跨天
                                            !laveReq.getcAcrossDay().equals("Y") &&
                                                    !StringUtils.isEmpty(laveReq.getcLeaDay1()) &&
                                                    laveReq.getStartDate() != null
                                    )
                    )
                    &&
                    !StringUtils.isEmpty(laveReq.getcWfEmplid())
                    ;
        } else {
            return true;
        }
    }


    private BigDecimal calcLeaveTime(WfPlaveHdrRespVO req) {
        if (!"Y".equalsIgnoreCase(req.getcAcrossDay())) {
            return "C".equalsIgnoreCase(req.getcLeaDay1()) ? BigDecimal.ONE : BigDecimal.valueOf(0.5);
        }
        String days = processService.calLeaveTime(req.getcWfEmplid(), req.getcLeaveType(),
                req.getcApplInfo(), DateUtils.format(new Date(), "yyyy-MM-dd"), req.getcAcrossDay(),
                DateUtils.format(req.getStartDate(), "yyyy-MM-dd"), req.getcLeaDay2(),
                DateUtils.format(req.getEndDate(), "yyyy-MM-dd"), req.getcLeaDay3());
        if (StringUtils.isEmpty(days)) {
            return BigDecimal.ZERO;
        } else {
            return new BigDecimal(days);
        }
    }

    @GetMapping(value = "/getLeaveType")
    public BaseResponseVO getLeaveType(@SessionGain("user") UserDTO user) {
        List<PsCLeaveTypeVw> items = psCLeaveTypeVwRepository.findAll(new Sort(Direction.ASC, "cLeaveType"));
        PsCLeaveDefnVw query = new PsCLeaveDefnVw();
        query.setEmplid(user.getEmplId());
        query.setEmplRcd(new BigDecimal(0));
        List<PsCLeaveDefnVw> leaveDefs = psCLeaveDefnVwRepository.findAll(Example.of(query));
        List<Map<String, String>> leaveTypes = new ArrayList<Map<String, String>>();
        Map<String, String> type;
        for (PsCLeaveTypeVw item : items) {
            type = new HashMap<>();
            type.put("name", item.getShortname());
            type.put("value", item.getcLeaveType());
            for (PsCLeaveDefnVw defn : leaveDefs) {
                if (item.getcLeaveType().equals(defn.getCLeaveType())) {
                    type.put("type", defn.getCLevaeUnit());
                    break;
                }
            }
            //规则没有时，已天来计算
            if (!type.containsKey("type")) {
                type.put("type", "D");
            }
            leaveTypes.add(type);
        }
        return buildRespone(leaveTypes, false);

    }

    @Override
    protected Set<String> getAuthFileds() {
        return null;
    }
}
